﻿using System;
using IGS.Core;
using IGS.Core.Evaluators;
using IGS.Core.Integrators;
using IGS.Core.Logging;
using IGS.Core.Models;
using IGS.Core.Systems;

namespace IGS.CLI
{
    static class Program
    {
        static Simulator SetupTwoBodyProlem()
        {
            var bodies = new IInteractable[]
            {
                new Body(1.0, new Vector(+0.5, 0, 0),  new Vector(0, -Math.Sqrt(0.5), 0)),
                new Body(1.0, new Vector(-0.5, 0, 0), new Vector(0, +Math.Sqrt(0.5), 0))
            };
            var evaluator = new PairwiseForceEvaluator();
            var integrator = new SymplecticEulerIntegrator();
            var logger = new Logger(Console.Out);
            var system = new NBodySystem(bodies);

            return new Simulator(system, evaluator, integrator, logger);
        }

        private static Simulator SetupPlummerProblem(int n)
        {
            var model = new PlummerModel();
            var system = model.Generate(n, 1.0, 1.0);
            var evaluator = new PairwiseForceEvaluator();
            var integrator = new SymplecticEulerIntegrator();
            var logger = new Logger(Console.Out);

            return new Simulator(system, evaluator, integrator, logger);
        }

        static void Main(string[] args)
        {
            Simulator simulator;
            if (args.Length < 1)
                simulator = SetupTwoBodyProlem();
            else
            {
                int n;
                if (!Int32.TryParse(args[0], out n))
                {
                    Console.WriteLine("Usage: IGS.exe [n: integer, optional]");
                    Environment.Exit(1);
                }

                simulator = SetupPlummerProblem(n);
            }

            var period = Math.PI * Math.Sqrt(2.0);
            const int steps = 100;
            const int iterations = 1;
            var dt = iterations * (period / steps);

            for (var t = 0.0; t <= period * iterations; t += dt)
                simulator.Evolve(dt);
        }
    }
}
